package keer.httpinterface.utils;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public final class ClassUtils {
    private ClassUtils() {

    }

    private static final Map<ClassLoader, List<String>> ALL_LOADER_CLASS_NAMES = new ConcurrentHashMap<>();

    /**
     * 获取所有类的名称
     *
     * 此方法用于获取当前线程上下文类加载器加载的所有类的名称通过调用此方法，
     * 可以得到一个包含所有类名的列表，便于进行进一步的处理或分析
     *
     * @return 包含所有类名的列表
     * @see Thread#getContextClassLoader()
     * @see ClassLoader
     */
    public static List<String> getAllClassNames() {
        return getAllClassNames(Thread.currentThread().getContextClassLoader());
    }
    /**
     * 获取指定类加载器加载的所有类名称
     * 此方法首先检查是否已经缓存了该类加载器加载的所有类名称如果已缓存，则直接返回缓存的结果
     * 否则，将同步处理类名称的获取和缓存，以避免重复计算和多次缓存
     *
     * @param loader 类加载器，用于获取其加载的所有类名称
     * @return 包含指定类加载器加载的所有类名称的列表
     */
    public static List<String> getAllClassNames(ClassLoader loader) {
        // 检查缓存中是否已存在该类加载器加载的所有类名称
        if (ALL_LOADER_CLASS_NAMES.containsKey(loader)) {
            return ALL_LOADER_CLASS_NAMES.get(loader);
        } else {
            // 同步代码块，防止多个线程同时计算和缓存相同类加载器的结果
            synchronized (ALL_LOADER_CLASS_NAMES) {
                // 再次检查缓存，防止在等待同步期间其他线程已经完成了缓存
                if (ALL_LOADER_CLASS_NAMES.containsKey(loader)) {
                    return ALL_LOADER_CLASS_NAMES.get(loader);
                } else {
                    // 扫描并获取类名称列表
                    List<String> classNames = scanClassNames(loader);
                    // 将结果缓存，以便下次快速访问
                    ALL_LOADER_CLASS_NAMES.put(loader, classNames);
                    return classNames;
                }
            }
        }
    }
    /**
     * 获取指定包下的所有类名称
     *
     * @param loader 类加载器，用于加载类
     * @param packageName 包名，表示需要获取类名称的包
     * @return 包含指定包下所有类名称的列表
     */
    public static List<String> getPackageClassNames(ClassLoader loader, String packageName) {
        // 初始化一个空的类名称列表
        List<String> classNames = new ArrayList<>();

        // 遍历所有类名称
        for (String className : getAllClassNames(loader)) {
            // 检查类名称是否以指定的包名开头
            if (className.startsWith(packageName)) {
                // 如果是，将类名称添加到列表中
                classNames.add(className);
            }
        }

        // 返回包含所有匹配类名称的列表
        return classNames;
    }
    /**
     * 获取指定包名下所有类的名称列表
     * 此方法重载了另一个具有相同名称的方法，使用当前线程的上下文类加载器
     *
     * @param packageName 包名，例如 "com.example.package"
     * @return 包含指定包下所有类名称的列表
     */
    public static List<String> getPackageClassNames(String packageName) {
        return getPackageClassNames(Thread.currentThread().getContextClassLoader(), packageName);
    }
    /**
     * 根据模式匹配获取类名列表
     *
     * @param loader 类加载器，用于获取类名
     * @param pattern 模式字符串，用于指定匹配模式
     * @return 匹配模式的类名列表
     */
    public static List<String> getClassNamesByPattern(ClassLoader loader, String pattern) {
        // 获取所有类名
        List<String> classNames = getAllClassNames(loader);

        // 判断模式是否为递归匹配
        boolean recursive = pattern.endsWith(".**");
        // 判断模式是否为匹配子包
        boolean child = pattern.endsWith(".*");

        // 移除模式中的匹配符号，用于后续的具体匹配
        pattern = pattern.replace(".**", "").replace(".*", "");

        // 存储匹配结果的列表
        List<String> result = new ArrayList<>();

        // 遍历所有类名进行匹配
        for (String name : classNames) {
            // 检查类名是否以模式开头
            if (name.startsWith(pattern)) {
                // 移除模式部分，获取剩余的类名部分
                String n = name.replaceFirst(pattern, "");

                // 如果剩余部分为空，且模式不包含递归或子包匹配，则添加到结果中
                if (n.isEmpty()) {
                    if (!(recursive || child)) {
                        result.add(name);
                    }
                } else {
                    // 如果剩余部分以点开始，表示是子包或子类
                    if (n.startsWith(".")) {
                        // 如果是递归匹配，则直接添加到结果中
                        if (recursive) {
                            result.add(name);
                        } else if (child) {
                            // 移除子包的点，准备进行进一步匹配
                            n = n.replaceFirst("\\.", "");
                            // 如果剩余部分不再包含点，表示是直接子包或子类，则添加到结果中
                            if (n.indexOf('.') < 0) {
                                result.add(name);
                            }
                        }
                    }
                }
            }
        }

        // 返回匹配结果
        return result;
    }

    /**
     * 使用指定的类加载器加载一组类
     * 此方法根据类名列表加载对应的类，并返回加载后的类对象列表
     * 如果类名列表为空或null，则返回null
     *
     * @param loader     类加载器，用于加载类如果为null，将使用系统类加载器
     * @param classNames 类名列表，包含需要加载的类的全限定名
     * @param initialize 是否初始化加载的类true表示初始化，false表示不初始化
     * @return 加载后的类对象列表如果输入列表为空或null，则返回null
     * @throws ClassNotFoundException 如果指定的类名对应的类找不到时抛出
     */
    public static List<Class<?>> loadClasses(ClassLoader loader, List<String> classNames, boolean initialize) throws ClassNotFoundException {
        List<Class<?>> classes = null;
        // 检查输入的类名列表是否非空
        if (classNames != null) {
            classes = new ArrayList<>();
            // 遍历类名列表，加载每个类
            for (String className : classNames) {
                // 使用类名加载类，initialize参数指定是否初始化类
                classes.add(Class.forName(className, initialize, loader));
            }
        }
        // 返回加载的类列表，如果输入为空则返回null
        return classes;
    }
    /**
     * 根据类名列表加载对应的类
     * 此方法主要用于动态加载类，可以根据给定的类名列表，利用当前线程上下文类加载器来加载这些类
     *
     * @param classNames 包含类名的列表，这些类名是待加载的类的全限定名
     * @return 返回一个List，其中包含根据classNames参数加载得到的Class对象
     * @throws ClassNotFoundException 如果在类加载过程中，给定的类名对应的类找不到，则抛出此异常
     */
    public static List<Class<?>> loadClasses(List<String> classNames) throws ClassNotFoundException {
        // 调用重载方法，传入当前线程的上下文类加载器、类名列表和一个布尔值true
        // 这里的重载方法可能负责实际的类加载逻辑，以及是否需要进行某些特殊处理（如初始化类）
        return loadClasses(Thread.currentThread().getContextClassLoader(), classNames, Boolean.TRUE);
    }
    /**
     * 使用指定的类加载器加载一组类
     * 此方法允许通过类名称数组来批量加载类，并可以选择是否初始化这些类
     * 它是通过委托给另一个重载方法loadClasses，后者接受类名称列表作为参数
     *
     * @param loader 类加载器，用于加载类如果为null，将使用系统类加载器
     * @param initialize 是否初始化加载的类true表示初始化，false表示不初始化
     * @param classNames 一个或多个类的全限定名，表示要加载的类
     * @return 返回加载的类的数组
     * @throws ClassNotFoundException 如果指定的类名称无法找到对应的类
     */
    public static Class<?>[] loadClasses(ClassLoader loader, boolean initialize, String... classNames) throws ClassNotFoundException {
        // 使用指定的类加载器和类名称列表加载类，并根据参数决定是否初始化
        List<Class<?>> classes = loadClasses(loader, Arrays.asList(classNames), initialize);
        // 将加载的类列表转换为数组并返回
        return classes.toArray(new Class<?>[0]);
    }
    /**
     * 加载指定的类
     *
     * @param classNames 一个或多个类的名称，用于指定需要加载的类
     * @return 返回一个Class对象数组，表示加载的类
     * @throws ClassNotFoundException 如果指定的类名称在当前类加载器中找不到，则抛出此异常
     */
    public static Class<?>[] loadClasses(String... classNames) throws ClassNotFoundException {
        // 调用重载方法，使用当前线程的上下文类加载器加载类
        return loadClasses(Thread.currentThread().getContextClassLoader(), Boolean.TRUE, classNames);
    }
    /**
     * 获取指定类的子类列表
     *
     * @param classes 待检查的类列表
     * @param superClass 指定的父类
     * @param includeAbstract 是否包括抽象类
     * @return 符合条件的子类列表
     *
     * 此方法用于从给定的类列表中筛选出指定父类的子类如果指定包括抽象类，则所有符合条件的子类都将被返回；
     * 否则，返回的列表将仅包含非抽象的子类
     */
    public static <T> List<Class<T>> getSubClasses(List<Class<?>> classes, Class<T> superClass, boolean includeAbstract) {
        List<Class<T>> result = new ArrayList<>();
        if (classes != null) {
            for (Class<?> clazz : classes) {
                // 检查当前类是否是指定父类的子类
                if (superClass.isAssignableFrom(clazz)) {
                    // 根据是否包括抽象类的参数决定是否添加抽象类
                    if (includeAbstract || !Modifier.isAbstract(clazz.getModifiers())) {
                        result.add((Class<T>) clazz);
                    }
                }
            }
        }
        return result;
    }
    /**
     * 根据包名获取指定父类的所有子类
     * 此方法通过类加载器加载指定包下的所有类，并筛选出继承自指定父类的子类
     * 主要用于反射操作，以动态加载和实例化对象
     *
     * @param loader          类加载器，用于加载类
     * @param packageName     包名，指定需要扫描的包
     * @param superClass      指定的父类，用于筛选子类
     * @param includeAbstract 是否包括抽象类，true表示包括，false表示不包括
     * @param initialize      是否初始化类，true表示初始化，false表示不初始化
     * @return 返回继承自指定父类的子类列表
     * @throws ClassNotFoundException 如果类加载失败，则抛出此异常
     */
    public static <T> List<Class<T>> getSubClassesByPackage(ClassLoader loader,
                                                            String packageName,
                                                            Class<T> superClass,
                                                            boolean includeAbstract,
                                                            boolean initialize) throws ClassNotFoundException {
        // 获取包下所有类名
        List<String> classNames = getPackageClassNames(loader, packageName);
        // 加载类
        List<Class<?>> classes = loadClasses(loader, classNames, initialize);
        // 筛选子类
        return getSubClasses(classes, superClass, includeAbstract);
    }
    /**
     * 根据包名获取指定父类的所有子类
     * 此方法主要用于反射查询，通过指定包名和父类，返回该包下所有该父类的子类列表
     *
     * @param packageName 包名，指定需要查询的包的名称
     * @param superClass 父类，指定需要查询的父类类型
     * @return 返回一个包含所有子类的列表
     * @throws ClassNotFoundException 当无法找到指定类时抛出此异常
     */
    public static <T> List<Class<T>> getSubClassesByPackage(String packageName, Class<T> superClass) throws ClassNotFoundException {
        // 调用重载方法，传入当前线程上下文类加载器，包名，父类，以及控制是否包含抽象类和是否递归查找子包的标志
        return getSubClassesByPackage(Thread.currentThread().getContextClassLoader(),
                packageName, superClass, Boolean.FALSE, Boolean.TRUE);
    }
    /**
     * 根据指定模式获取符合该模式的所有类中，继承自指定父类的子类列表
     *
     * @param loader 类加载器，用于加载类
     * @param pattern 类名模式，用于筛选符合条件的类
     * @param superClass 指定的父类类型
     * @param includeAbstract 是否包括抽象类，true表示包括，false表示不包括
     * @param initialize 是否初始化类，true表示初始化，false表示不初始化
     * @return 返回继承自指定父类的子类列表
     * @throws ClassNotFoundException 如果类加载过程中出现错误
     */
    public static <T> List<Class<T>> getSubClassesByPattern(ClassLoader loader, String pattern, Class<T> superClass, boolean includeAbstract, boolean initialize) throws ClassNotFoundException {
        // 根据模式获取所有类名
        List<String> classNames = getClassNamesByPattern(loader, pattern);
        // 加载类
        List<Class<?>> classes = loadClasses(loader, classNames, initialize);
        // 筛选继承自指定父类的子类
        return getSubClasses(classes, superClass, includeAbstract);
    }
    /**
     * 根据模式获取指定类的子类列表
     * 该方法使用系统类加载器来查找符合模式的子类
     *
     * @param pattern 模式字符串，用于匹配类名
     * @param superClass 指定的父类类型
     * @return 返回符合模式的子类列表
     * @throws ClassNotFoundException 如果无法找到符合模式的子类，则抛出此异常
     */
    public static <T> List<Class<T>> getSubClassesByPattern(String pattern, Class<T> superClass) throws ClassNotFoundException {
        // 调用重载方法，使用当前线程的上下文类加载器，不包括抽象类，包括实现类
        return getSubClassesByPattern(Thread.currentThread().getContextClassLoader(),
                pattern, superClass, Boolean.FALSE, Boolean.TRUE);
    }
    /**
     * 扫描类名称
     * 该方法用于扫描指定类加载器下的所有类文件，并将其全限定名添加到一个列表中
     * 它处理jar文件、单个类文件以及包含类文件的目录
     *
     * @param loader 类加载器，用于获取类路径URL
     * @return 包含所有扫描到的类全限定名的只读列表
     */
    private static List<String> scanClassNames(ClassLoader loader) {
        // 创建一个列表，用于存储扫描到的类名称
        List<String> classNames = new ArrayList<>();
        // 获取类加载器的所有URL路径
        URL[] urls = ((URLClassLoader) loader).getURLs();
        // 遍历每个URL路径
        for (URL url : urls) {
            // 获取URL的路径字符串
            String path = url.getPath();
            // 如果路径是jar文件，则调用scanJarClassNames方法扫描jar文件中的类名称
            if (path.endsWith(".jar")) {
                classNames.addAll(scanJarClassNames(path));
            // 如果路径是类文件，则直接将类名称添加到列表中
            } else if (path.endsWith(".class")) {
                classNames.add(pathToClassName(path));
            // 如果路径是目录，则调用scanDirClassNames方法扫描目录下的类名称
            } else {
                classNames.addAll(scanDirClassNames(path, new File(path)));
            }
        }
        // 返回包含所有类名称的只读列表
        return Collections.unmodifiableList(classNames);
    }
    /**
     * 扫描类路径中的指定文件
     * 该方法用于查找类路径中所有匹配指定文件名的资源，主要用于处理在不同的类路径（如jar包、目录）中同名文件的查找
     *
     * @param classLoader 类加载器，用于获取类路径中的资源
     * @param fileName 要扫描的文件名
     * @return 包含所有匹配文件的URL列表
     * @throws IOException 如果资源获取过程中发生I/O错误
     */
    public static List<URL> scanClasspathFiles(ClassLoader classLoader, String fileName) throws IOException {
        // 获取类路径中所有匹配指定文件名的资源
        Enumeration<URL> resources = classLoader.getResources(fileName);
        List<URL> files = new ArrayList<>();
        // 遍历资源并添加到列表中
        while (resources.hasMoreElements()) {
            files.add(resources.nextElement());
        }
        return files;
    }
    /**
     * 读取属性文件内容
     * 该方法从一个URL列表中读取属性文件，并将它们的内容合并为一个字符串返回
     * 主要用于处理多个属性文件的批量读取和合并
     *
     * @param urls 包含属性文件路径的URL列表
     * @param charset 用于读取属性文件的字符集
     * @return 合并后包含所有属性文件内容的字符串
     * @throws IOException 如果读取文件过程中发生错误
     */
    public static String readPropertiesFile(List<URL> urls, String charset) throws IOException {
        StringBuilder builder = new StringBuilder();
        for (URL url : urls) {
            // 读取每个URL对应的属性文件内容，并追加到StringBuilder中
            builder.append(IOUtils.readText(url.openStream(), charset))
                    .append("\n");
        }
        // 返回合并后的字符串
        return builder.toString();
    }
    /**
     * 从多个URL中读取属性文件，并解析成键值对的映射
     * 该方法首先读取所有URL指向的属性文件内容，然后按行解析这些内容，
     * 忽略注释行和空行，将有效的属性按键值对的形式存储在映射中
     *
     * @param urls 包含属性文件的URL列表这些URL指示了属性文件的位置
     * @param charset 读取属性文件时使用的字符集
     * @return 返回一个映射，其中键是属性名，值是属性值的列表
     * @throws IOException 如果读取文件时发生I/O错误
     */
    public static Map<String, List<String>> readProperties(List<URL> urls, String charset) throws IOException {
        // 读取属性文件内容
        String text = readPropertiesFile(urls, charset);
        // 规范化文本，将多行文本合并为一行，用逗号分隔原来的行
        text = text.trim().replaceAll("(\\\\\r\n)|(\\\\\n)", ",");
        // 按行分割规范化后的文本
        String[] arr = text.split("(\n)|(\r\n)");
        // 创建一个有序映射，用于存储解析后的键值对
        Map<String, List<String>> result = new LinkedHashMap<>();
        for (String s : arr) {
            // 忽略注释行
            if (s.trim().startsWith("#")) {
                continue;
            }
            // 分割行内容，解析键值对
            String[] linArr = s.split("=");
            // 获取键，忽略无效的键
            String key = linArr[0].trim();
            if (StringUtils.isBlank(key)) {
                continue;
            }
            // 如果键不存在，则创建一个新的值列表
            List<String> list = result.computeIfAbsent(key, k -> new ArrayList<>());
            // 如果存在值，则解析值并添加到列表中
            if (linArr.length > 1) {
                String[] valArr = linArr[1].trim().split(",");
                for (String v : valArr) {
                    // 忽略无效的值
                    if (!StringUtils.isBlank(v)) {
                        list.add(v.trim());
                    }
                }
            }
        }
        // 返回解析后的键值对映射
        return result;
    }
    /**
     * 扫描目录及其子目录中的类名
     * 此方法用于递归地扫描指定路径及其所有子目录中的所有类名
     * 它会处理目录中的所有文件和子目录，对于.jar文件，它会调用另一个方法来获取类名
     * 对于.class文件，它会根据文件路径生成类名
     *
     * @param path 当前扫描的目录路径
     * @param basicDir 基础目录，用于计算相对路径
     * @return 包含所有扫描到的类名的列表
     */
    private static List<String> scanDirClassNames(String path, File basicDir) {
        // 创建File对象以操作指定路径
        File file = new File(path);
        // 初始化一个列表来存储类名
        List<String> classNames = new ArrayList<>();
        // 检查文件是否存在且为目录
        if (file.exists() && file.isDirectory()) {
            // 获取目录中的所有文件和子目录
            File[] files = file.listFiles();
            // 如果文件数组不为空，则遍历每个文件或子目录
            if (files != null) {
                for (File f : files) {
                    // 如果是子目录，则递归调用当前方法
                    if (f.isDirectory()) {
                        classNames.addAll(scanDirClassNames(f.getPath(), basicDir));
                        continue;
                    }
                    // 获取当前文件的路径
                    String p = f.getPath();
                    // 如果是.jar文件，则调用另一个方法来获取类名
                    if (p.endsWith(".jar")) {
                        classNames.addAll(scanJarClassNames(p));
                    } else if (p.endsWith(".class")) {
                        // 对于.class文件，计算其相对于基础目录的路径
                        Path p1 = Paths.get(basicDir.getPath());
                        Path p2 = Paths.get(p);
                        p = p1.relativize(p2).toString();
                        // 根据文件路径生成类名并添加到列表中
                        classNames.add(pathToClassName(p));
                    }
                }
            }
        }
        // 返回包含所有类名的列表
        return classNames;
    }
    /**
     * 扫描Jar文件中的类名称
     * 此方法旨在打开指定路径的Jar文件，并扫描其中的所有类名称
     * 它通过检查Jar文件中的每个条目，找出所有以".class"结尾的文件，将其路径转换为类名称格式，并收集这些名称
     *
     * @param path Jar文件的路径，用于定位要扫描的Jar文件
     * @return 包含Jar文件中所有类名称的列表如果Jar文件中没有类文件，则返回空列表
     * @throws RuntimeException 如果在读取Jar文件时遇到IOException，则包装并抛出RuntimeException
     */
    private static List<String> scanJarClassNames(String path) {
        List<String> classNames = new ArrayList<>();
        try (JarFile jarFile = new JarFile(path)) {
            Enumeration<JarEntry> entries = jarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String name = entry.getName();
                if (name.endsWith(".class")) {
                    classNames.add(pathToClassName(name));
                }
            }
        } catch (FileNotFoundException e) {
            // 文件未找到异常处理留空，调用者应确保路径正确
        } catch (IOException e) {
            // 文件读取过程中发生IO异常，包装为运行时异常并抛出
            throw new RuntimeException(e);
        }
        return classNames;
    }
    /**
     * 将POJO对象读取为键值对映射
     * 此方法用于将给定的POJO对象转换为Map对象，其中包含对象的所有非静态字段及其值
     * 可以选择是否包括父类字段和是否排除transient字段
     *
     * @param pojo 要转换为Map的POJO对象
     * @param containsSuper 是否包括父类字段
     * @param excludeTransient 是否排除transient字段
     * @return 包含POJO对象字段及其对应值的Map对象
     */
    public static Map<String, Object> readPojoAsMap(Object pojo, boolean containsSuper, boolean excludeTransient) {
        // 初始化一个空的LinkedHashMap以存储字段名和字段值
        Map<String, Object> result = new LinkedHashMap<>();
        // 检查传入的POJO对象是否不为null
        if (pojo != null) {
            // 获取POJO对象的所有字段，根据containsSuper参数决定是否包括父类字段
            List<Field> fields = getDeclaredFields(pojo.getClass(), containsSuper);
            // 遍历所有字段
            for (Field field : fields) {
                // 跳过静态字段，以及当excludeTransient为false时的transient字段
                if (Modifier.isStatic(field.getModifiers())
                        || (Modifier.isTransient(field.getModifiers()) && !excludeTransient)) {
                    continue;
                }
                // 获取当前字段的值
                Object value = getFieldValue(field, pojo);
                // 如果字段值为null，则跳过
                if (value == null) {
                    continue;
                }
                // 将字段名和字段值作为键值对放入结果Map中
                result.put(field.getName(), value);
            }
        }
        // 返回包含所有非静态、非transient字段及其值的Map对象
        return result;
    }
    /**
     * 获取类的声明方法
     *
     * @param clazz 要检查的类
     * @param includeSuper 是否包括父类方法
     * @return 类（可能包括父类）的声明方法数组
     */
    public static Method[] getDeclaredMethods(Class<?> clazz, boolean includeSuper) {
        // 根据includeSuper标志决定是否获取父类方法
        return includeSuper ? clazz.getMethods() : clazz.getDeclaredMethods();
    }
    /**
     * 获取类声明的所有字段，包括公共、保护、默认访问和私有字段
     *
     * @param clazz 要检查的类
     * @param includeSuper 是否包括超类的字段
     * @return 包含类声明的所有字段的列表如果includeSuper为true且类有超类，则包括超类的字段
     */
    public static List<Field> getDeclaredFields(Class<?> clazz, boolean includeSuper) {
        // 获取当前类声明的所有字段
        Field[] fields = clazz.getDeclaredFields();
        // 将当前类的字段数组转换为列表
        List<Field> result = new ArrayList<>(Arrays.asList(fields));
        // 如果需要包括超类字段且当前类的超类不是Object类
        if (includeSuper && !clazz.getSuperclass().equals(Object.class)) {
            // 递归调用getDeclaredFields方法，获取超类字段并添加到结果列表中
            result.addAll(getDeclaredFields(clazz.getSuperclass(), Boolean.TRUE));
        }
        // 返回包含当前类及其超类（如果指定）所有字段的列表
        return result;
    }

    /**
     * 获取指定名称的字段，包括超类字段
     * @param name 字段名称
     * @param clazz 要检查的类
     * @param includeSuper 是否包括超类字段
     * @return 字段对象，如果不存在则返回null
     */
    public static Field getDeclaredField(String name, Class<?> clazz, boolean includeSuper) {
        List<Field> fs = getDeclaredFields(clazz, includeSuper);
        for (Field f : fs) {
            if (f.getName().equals(name)) {
                return f;
            }
        }
        return null;
    }
    /**
     * 获取指定字段的值
     * 该方法通过反射获取对象中指定字段的值，忽略字段的访问权限限制
     *
     * @param field 字段对象，表示需要访问的字段
     * @param instance 实例对象，表示需要从该实例中获取字段值如果为null，尤其是静态字段访问时，此参数允许为null
     * @return 字段的值，返回类型为Object，可以根据实际情况进行类型转换
     * @throws RuntimeException 如果由于访问权限问题或其它原因无法访问字段时，抛出运行时异常
     */
    public static Object getFieldValue(Field field,Object instance) {
        // 设置字段为可访问，即使它是私有的或受保护的
        field.setAccessible(Boolean.TRUE);
        try {
            // 尝试获取字段的值
            return field.get(instance);
        } catch (IllegalAccessException e) {
            // 如果发生访问异常，转换为运行时异常并重新抛出
            throw new RuntimeException(e);
        }
    }
    /**
     * 将文件路径转换为Java类名
     * 此方法旨在处理Java类文件路径，去除路径中的文件扩展名.class，并将路径中的目录分隔符替换为Java类名中的点号
     * 从而将文件系统路径转换为符合Java语言习惯的类名表示形式
     *
     * @param path 表示Java类文件的路径，应以.class结尾
     * @return 转换后的Java类名字符串，不包含路径分隔符和文件扩展名
     */
    private static String pathToClassName(String path) {
        // 移除路径末尾的".class"，并统一替换路径中的目录分隔符为点号
        return path.substring(0, path.length() - ".class".length()).replace('/', '.').replace("\\", ".");
    }
    /**
     * 判断给定对象是否为基本类型或其包装类
     * 该方法用于检查一个对象是否属于以下几类：
     * - 基本类型
     * - 基本类型的包装类
     * - CharSequence接口的实现类（如String）
     * - Number类的子类（如Integer, Double）
     * - Boolean类的实例
     * 这种检查在处理数据时非常有用，特别是在需要对输入进行类型限制时
     *
     * @param o 待检查的对象
     * @return 如果对象是基本类型或其包装类，则返回true；否则返回false
     */
    public static boolean isPrimitiveOrWrapper(Object o) {
        // 检查对象是否为null，因为null不是任何类型的实例
        if (o == null) {
            return Boolean.FALSE;
        }
        // 检查对象是否为CharSequence、Number、Boolean的实例之一，
        // 或者对象的类是基本类型（通过isPrimitive方法判断）
        return o instanceof CharSequence || o instanceof Number || o instanceof Boolean || o.getClass().isPrimitive();
    }
    /**
     * 判断给定的类是否为基本类型或其包装类
     * <p>
     * 该方法用于确定一个类是不是Java的基本类型（如int、boolean）或其对应的包装类（如Integer、Boolean）
     * 它通过检查类是否属于CharSequence或Number的子类，或者直接是基本类型来做出判断
     *
     * @param clazz 要检查的类
     * @return 如果类是基本类型或其包装类，则返回true；否则返回false
     */
    public static boolean isPrimitiveOrWrapperClass(Class<?> clazz) {
        // 检查类是否为CharSequence的子类，CharSequence接口由字符串类实现
        return CharSequence.class.isAssignableFrom(clazz) ||
                // 检查类是否为Number的子类，Number类是所有数值类型包装类的父类
                Number.class.isAssignableFrom(clazz) ||
                // 直接检查类是否为基本类型
                clazz.isPrimitive();
    }
}
